package com.slipper.bpmn.model;

import java.util.ArrayList;
import java.util.List;

public class Bpmn {
    public static final String START_NODE = "startEvent";
    public static final String TASK_NODE = "task";
    public static final String SCRIPT_NODE = "scriptTask";
    public static final String BRANCH_NODE = "exclusiveGateway";
    public static final String PARALLEL_NODE = "parallelGateway";
    public static final String MERGE_NODE = "complexGateway";
    public static final String LINE_NODE = "sequenceFlow";
    public static final String END_NODE = "endEvent";
    
    private StartNode startNode;
    private EndNode endNode;
    private List<TaskNode> taskNodeList = new ArrayList<>();
    private List<Gateway> gatewayList = new ArrayList<>();
    private List<Line> lineList = new ArrayList<>();
    private final StringBuilder errorMsg = new StringBuilder();

    public void add(Object object) {
        switch (object) {
            case StartNode node -> this.add(node);
            case EndNode node -> this.add(node);
            case TaskNode taskNode -> this.add(taskNode);
            case Gateway gateway -> this.add(gateway);
            case Line line -> this.add(line);
            case null, default -> throw new RuntimeException("未定义的类型！");
        }
    }
    
    public void validate() {
        if (!this.errorMsg.isEmpty()) {
            return;
        }
        
        if (this.startNode == null) {
            this.appendError("开始节点不存在！");
        }
        if (this.taskNodeList.isEmpty()) {
            this.appendError("人工节点不存在！");
        }
        if (this.lineList.isEmpty()) {
            this.appendError("节点连线不存在！");
        }
        if (this.endNode == null) {
            this.appendError("结束节点不存在！");
        }
        
        int parallel = 0;
        int merge = 0;
        for (Gateway gateway : gatewayList) {
            if (Bpmn.PARALLEL_NODE.equals(gateway.getType())) {
                parallel++;
            }
            if (Bpmn.MERGE_NODE.equals(gateway.getType())) {
                merge++;
            }
        }
        if (parallel != merge) {
            this.appendError("并行开始节点数量与并行节点数量不一致！");
        }
    }
    
    public void add(StartNode startNode) {
        this.startNode = startNode;
    }

    public void add(EndNode endNode) {
        this.endNode = endNode;
    }

    public void add(TaskNode taskNode) {
        this.taskNodeList.add(taskNode);
    }

    public void add(Gateway gateway) {
        this.gatewayList.add(gateway);
    }

    public void add(Line line) {
        this.lineList.add(line);
    }

    public StartNode getStartNode() {
        return startNode;
    }

    public void setStartNode(StartNode startNode) {
        this.startNode = startNode;
    }

    public EndNode getEndNode() {
        return endNode;
    }

    public void setEndNode(EndNode endNode) {
        this.endNode = endNode;
    }

    public List<TaskNode> getTaskNodeList() {
        return taskNodeList;
    }

    public void setTaskNodeList(List<TaskNode> taskNodeList) {
        this.taskNodeList = taskNodeList;
    }

    public List<Gateway> getGatewayList() {
        return gatewayList;
    }

    public void setGatewayList(List<Gateway> gatewayList) {
        this.gatewayList = gatewayList;
    }

    public List<Line> getLineList() {
        return lineList;
    }

    public void setLineList(List<Line> lineList) {
        this.lineList = lineList;
    }

    public String getErrorMsg() {
        return errorMsg.toString();
    }

    public void appendError(String errorMsg) {
        this.errorMsg.append(errorMsg);
    }
}
